﻿using AutoMapper;
using B.Z.BasicData.Infrastructure;
using B.Z.Inventory.API.Write.Application.Command;
using B.Z.Inventory.Domain;
using B.Z.Inventory.ErrorCode;
using MediatR;

namespace B.Z.Inventory.API.Write.Application.CommandHandler
{
    public class IntOutStoreAddCommandHandler : IRequestHandler<IntOutStoreAddCommand, APIResult<int>>
    {
        private readonly IBaseRepository<T_IntOutStore> inoutstoreRepository;
        private readonly IBaseRepository<T_Goods> goodsRepository;
        private readonly IBaseRepository<T_InventoryTask> taskRepository;
        private readonly IMapper mapper;
        private readonly ILogger<IntOutStoreAddCommandHandler> logger;
        public IntOutStoreAddCommandHandler(IBaseRepository<T_IntOutStore> inoutstoreRepository, IMapper mapper, ILogger<IntOutStoreAddCommandHandler> logger, IBaseRepository<T_Goods> goodsRepository, IBaseRepository<T_InventoryTask> taskRepository)
        {
            this.inoutstoreRepository = inoutstoreRepository;
            this.mapper = mapper;
            this.logger = logger;
            this.goodsRepository = goodsRepository;
            this.taskRepository = taskRepository;
        }

        public async Task<APIResult<int>> Handle(IntOutStoreAddCommand request, CancellationToken cancellationToken)
        {
            APIResult<int> result = new APIResult<int>();
            result.Code = APIEnums.ok;
            var model = mapper.Map<T_IntOutStore>(request);
            // 根据IsIntOrOut字段区分入库和出库操作
            if (request.IsIntOrOut == true)
            {
                result.Message = "入库成功，系统库存已同步更新";
                logger.LogInformation("执行入库操作");
            }
            else 
            {
                result.Message = "出库成功，系统库存已同步更新";
                logger.LogInformation("执行出库操作");
            }
            
            // 解析选中的商品ID
            var ids = request.GoodsIds.Split(',').Select(x => Convert.ToInt32(x)).ToArray();
            // 先获取商品数据，然后在内存中按照ID顺序排序
            var goodlist = goodsRepository.GetAll().Where(x => ids.Contains(x.Id)).ToList()
                .OrderBy(x => Array.IndexOf(ids, x.Id)).ToList();
            
            // 解析差异数量数组字符串
            var differentCounts = new int[goodlist.Count];
            if (!string.IsNullOrEmpty(request.DifferentCount))
            {
                var differentCountStrings = request.DifferentCount.Split(',');
                for (int i = 0; i < Math.Min(differentCountStrings.Length, goodlist.Count); i++)
                {
                    if (int.TryParse(differentCountStrings[i], out int differentCount))
                    {
                        differentCounts[i] = differentCount;
                    }
                }
            }
            
            // 解析实际库存数量数组字符串
            var actualNums = new int[goodlist.Count];
            if (!string.IsNullOrEmpty(request.ActualNums))
            {
                var actualNumStrings = request.ActualNums.Split(',');
                for (int i = 0; i < Math.Min(actualNumStrings.Length, goodlist.Count); i++)
                {
                    if (int.TryParse(actualNumStrings[i], out int actualNum))
                    {
                        actualNums[i] = actualNum;
                    }
                }
            }
            
            logger.LogInformation($"开始处理 {goodlist.Count} 个商品的库存更新");
            logger.LogInformation($"差异数量数组: [{string.Join(", ", differentCounts)}]");
            logger.LogInformation($"实际库存数组: [{string.Join(", ", actualNums)}]");
            
            // 打印每个货品的当前状态
            logger.LogInformation("货品当前状态:");
            for (int i = 0; i < goodlist.Count; i++)
            {
                var goods = goodlist[i];
                logger.LogInformation($"  货品{i + 1}: ID={goods.Id}, 名称={goods.GoodsName}, 系统库存={goods.SystemNum}, 实际库存={goods.ActualNum}, 差异={goods.DifferentCount}");
            }
            



            using (var ts = inoutstoreRepository.Context.Database.BeginTransaction()) 
            {
                try
                {
                    // 更新盘点任务状态
                    var tasks = taskRepository.GetAll().FirstOrDefault(x => x.InventoryNnumber == request.InventoryId);
                    if (tasks != null)
                    {
                        tasks.InventoryStatus = 2; // 设置为已完成状态
                        await taskRepository.Update(tasks);
                        logger.LogInformation($"更新盘点任务状态：{request.InventoryId}");
                    }

                    // 更新每个选中商品的库存
                    for (int i = 0; i < goodlist.Count; i++)
                    {
                        var item = goodlist[i];
                        var currentDifferentCount = differentCounts[i];
                        var currentActualNum = actualNums[i]; // 从前端传递的实际库存数组获取值
                        
                        // 记录原始库存信息
                        var originalSystemNum = item.SystemNum;
                        var originalActualNum = item.ActualNum;
                        var originalDifferentCount = item.DifferentCount;
                        
                        logger.LogInformation($"更新商品库存 - ID: {item.Id}, 商品名称: {item.GoodsName}");
                        logger.LogInformation($"  原系统库存: {originalSystemNum}, 原实际库存: {originalActualNum}, 原差异: {originalDifferentCount}");
                        logger.LogInformation($"  前端传递的差异值: {currentDifferentCount}");
                        logger.LogInformation($"  前端传递的实际库存: {currentActualNum}");
                        
                        // 核心逻辑：将系统库存更新为前端传递的实际库存值
                        if (currentActualNum > 0)
                        {
                            // 使用前端传递的实际库存值更新系统库存和实际库存
                            item.SystemNum = currentActualNum;
                            item.ActualNum = currentActualNum;
                            item.DifferentCount = 0; // 差异数量归零（因为系统库存已同步为实际库存）
                            
                            logger.LogInformation($"  系统库存已更新为前端传递值: {currentActualNum}");
                        }
                        else if (item.ActualNum.HasValue)
                        {
                            // 备用逻辑：使用数据库中的实际库存值
                            var newSystemNum = item.ActualNum.Value;
                            item.SystemNum = newSystemNum;
                            item.DifferentCount = 0;
                            
                            logger.LogInformation($"  使用数据库实际库存值更新系统库存: {newSystemNum}");
                        }
                        else
                        {
                            // 如果都没有数据，保持原有逻辑
                            logger.LogWarning($"  货品 {item.Id} 没有有效的实际库存数据，保持原系统库存: {item.SystemNum}");
                        }
                        
                        logger.LogInformation($"  新系统库存: {item.SystemNum}, 新实际库存: {item.ActualNum}, 新差异: {item.DifferentCount}");
                        
                        await goodsRepository.Update(item);
                    }
                    
                    // 添加出入库记录
                    result.Data = await inoutstoreRepository.Add(model);
                    logger.LogInformation($"添加出入库记录成功，记录ID: {result.Data}");
                    
                    ts.Commit();
                    logger.LogInformation("事务提交成功，所有操作已完成");
                }
                catch (Exception ex)
                {
                    logger.LogError(ex, "处理出入库操作时发生错误，正在回滚事务");
                    ts.Rollback();
                    result.Code = APIEnums.fail;
                    result.Message = "操作失败：" + ex.Message;
                }
            };
            return Task.FromResult(result).Result;
        }
    }
}
